package com.sjh.baseui.picture

import android.app.Activity
import android.app.Fragment
import android.content.Context
import android.graphics.Bitmap
import android.graphics.drawable.Drawable
import android.graphics.drawable.PictureDrawable
import android.view.View
import android.widget.ImageView
import androidx.fragment.app.FragmentActivity
import com.bumptech.glide.RequestBuilder
import com.bumptech.glide.load.DataSource
import com.bumptech.glide.load.MultiTransformation
import com.bumptech.glide.load.Transformation
import com.bumptech.glide.load.engine.DiskCacheStrategy
import com.bumptech.glide.load.engine.GlideException
import com.bumptech.glide.load.resource.bitmap.CenterCrop
import com.bumptech.glide.load.resource.bitmap.CenterInside
import com.bumptech.glide.load.resource.bitmap.CircleCrop
import com.bumptech.glide.load.resource.bitmap.FitCenter
import com.bumptech.glide.load.resource.gif.GifDrawable
import com.bumptech.glide.request.RequestListener
import com.bumptech.glide.request.RequestOptions
import com.bumptech.glide.request.target.Target
import com.sjh.baseutils.dp
import com.sjh.baseui.picture.glide.GlideApp
import com.sjh.baseui.picture.glide.GlideRequests
import com.sjh.baseui.picture.svg.SvgSoftwareLayerSetter
import jp.wasabeef.glide.transformations.RoundedCornersTransformation

/**
 * 最终加载图片的神秘之处
 */
object BuildImage {

    /**
     * 加载图片
     *
     * @param view 要显示的控件
     * @param url 要加载的图片，可能是网络图片地址，可能是本地图片地址，也可能是本地图片文件，也可能是图片资源id
     * @param any 被依赖的生命周期，可以是Activity，fragment，view等
     * @param build 图片构造器
     */
    fun showImage(view: ImageView, url: Any, any: Any?, build: ImageBuild) {
        showImageFromGlide(view, url, any, build)
    }

    /**
     * 通过glide加载图片
     *
     * @param view 要显示的控件
     * @param url 要加载的图片，可能是网络图片地址，可能是本地图片地址，也可能是本地图片文件，也可能是图片资源id
     * @param any 被依赖的生命周期，可以是Activity，fragment，view等
     * @param build 图片构造器
     */
    internal fun showImageFromGlide(view: ImageView, url: Any, any: Any?, build: ImageBuild) {

        //后置处理形状，突破形状的束缚
        val native = arrayListOf<Transformation<Bitmap>>()
        //处理圆角和圆形
        if(build.isCircle){
            native.add(CircleCrop())
        }else{
            //处理拉伸
            when (build.scaleType) {
                ImageScaleType.FitCenter -> native.add(FitCenter())
                ImageScaleType.FitXY -> native.add(
                    FitXY()
                )
                ImageScaleType.CenterCrop -> native.add(CenterCrop())
                ImageScaleType.CenterInside -> native.add(CenterInside())
                ImageScaleType.NONE -> {
                }
            }
            //处理圆角和圆形
            if (build.cornerRadius > 0f) {
                native.add(
                    RoundedCornersTransformation(
                        build.cornerRadius.dp.toInt(),
                        0,
                        RoundedCornersTransformation.CornerType.ALL
                    )
                )
            }
        }
        // 初始化requestOptions
        val requestOptions = RequestOptions()
            .placeholder(build.placeImage)
            .error(build.errorImage)
            .diskCacheStrategy(DiskCacheStrategy.RESOURCE)
            .optionalTransform(MultiTransformation(native))

        //判断图片依赖的容器是什么
        val glideRequests = when (any) {
            is Fragment -> GlideApp.with(any)
            is androidx.fragment.app.Fragment -> GlideApp.with(any)
            is FragmentActivity -> GlideApp.with(any)
            is Activity -> GlideApp.with(any)
            is Context -> GlideApp.with(any)
            is View -> GlideApp.with(any)
            else -> GlideApp.with(LibPicture.APPLICATION_CONTEXT)
        }

        var strUrl = url as? String
        if (strUrl != null && strUrl.endsWith(".svg")) {
            glideRequests.`as`(PictureDrawable::class.java).load(url)
                .apply(requestOptions)
                .skipMemoryCache(false)
                .diskCacheStrategy(DiskCacheStrategy.DATA)
                .dontAnimate()
                .listener(SvgSoftwareLayerSetter())
                .into(view)
        } else {
            // 加载图片
            glideRequests.load(url)
                .apply(requestOptions)
                .skipMemoryCache(false)
                .diskCacheStrategy(DiskCacheStrategy.DATA)
                .thumbnail(
                    loadTransform(
                        glideRequests,
                        requestOptions
                    )
                )
                .dontAnimate()
                .into(view)
        }
    }

    /**
     * 加载GIF
     *
     * @param url 要加载的gif图片，可能是网络gif图片地址，可能是本地gif图片地址，也可能是本地图片gif文件，也可能是图片资源gif_id
     * @param any 被依赖的生命周期，可以是Activity，fragment，view等
     * @param view 容器 这里只能设置 ImageView
     * @param count 需要gif播放循环的次数 默认为 一次
     */
    fun showGif(url: Any, any: Any, view: ImageView, count: Int) {
        //判断图片依赖的容器是什么
        val glideRequests = when (any) {
            is Fragment -> GlideApp.with(any)
            is androidx.fragment.app.Fragment -> GlideApp.with(any)
            is FragmentActivity -> GlideApp.with(any)
            is Activity -> GlideApp.with(any)
            is Context -> GlideApp.with(any)
            is View -> GlideApp.with(any)
            else -> GlideApp.with(LibPicture.APPLICATION_CONTEXT)
        }
        glideRequests
            .asGif()
            .load(url)
            .listener(object : RequestListener<GifDrawable> {
                override fun onResourceReady(
                    resource: GifDrawable?,
                    model: Any?,
                    target: Target<GifDrawable>?,
                    dataSource: DataSource?,
                    isFirstResource: Boolean
                ): Boolean {
                    resource?.setLoopCount(count)
                    return false
                }

                override fun onLoadFailed(
                    e: GlideException?,
                    model: Any?,
                    target: Target<GifDrawable>?,
                    isFirstResource: Boolean
                ): Boolean {
                    return false
                }
            })
            .into(view)
    }

    /**
     * 占位图处理成具有圆角或圆形的效果
     * @param requests
     * @param placeHolder
     * @param options
     */
    private fun loadTransform(requests: GlideRequests,
                              options: RequestOptions
    ): RequestBuilder<Drawable?>? {
        return requests
            .load(options.placeholderId)
            .error(options.errorId)
            .apply(options)
    }

}